#include "commandexecutor.h"
#include "CmdUtil.h"
#include "ProcessThread.h"
#include <shlobj.h>
#include <objbase.h>
#include <shellapi.h>
#include <winnt.h>
#include <combaseapi.h>

CommandExecutor::CommandExecutor(QObject *parent)
    : QObject{parent}
{}



void CommandExecutor::executeCommand(const QString &command) {
    // 获取系统环境变量
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();

    QString path = env.value("PATH");
    path.prepend("C:\\windows;");
    env.insert("PATH", path);
    // 获取%WINDIR%环境变量的值
    QString windir = env.value("WINDIR");
    env.insert("WINDIR", windir);
    process.setProcessEnvironment(env);
    // 输出结果
    qDebug() << "WINDIR:" << windir;

    QString program;
    QStringList arguments;
    if(command.startsWith("@.")){
        //以@.开头
        qDebug() << "11111111111111111111111111111:";
        CmdUtil::parseCommandAtSymbolWithPath(command,program, arguments);
        this->executeCommand(program,arguments);

    }else     if (command.startsWith("http://") || command.startsWith("https://")) {
        qDebug() << "------->http";
        openUrl(command);
    } else if (QFileInfo(command).isExecutable() && !command.endsWith(".lnk")) {
        qDebug() << "------->可执行非lnk";
        startExecutable(command,arguments);
    } else if (command.endsWith(".lnk")) {
        qDebug() << "------->lnk";
        openShortcut(command);
    } else if (command.contains(".exe") || command.contains(".bat") || command.contains(".cmd")) {
        qDebug() << "------->exe-bat-cmd";
        // replaceAtSymbolWithCurrentPath(command);
        startProcess(command, arguments);
    } else if (command.length() == 2 && command.endsWith(":")) {
        openDrive(command);
    } else if (command.length() == 3 && (command.endsWith("\\") || command.endsWith("/"))) {
        openDrive(command);
    } else if (systemIdentifiers.contains(command)) {
        qDebug() << "------->file";
        QString guid = systemIdentifiers.value(command);
        QUrl url("file:///" + guid);
        if (!QDesktopServices::openUrl(url)) {
            qDebug() << "Failed to open" << command;
        } else {
            qDebug() << "Opened" << command;
        }

        // QUrl controlPanelUrl("file:///::{21EC2020-3AEA-1069-A2DD-08002B30309D}");
        // if (!QDesktopServices::openUrl(controlPanelUrl)) {
        //     qDebug() << "Failed to open '控制面板'";
        // }
    }else{
        runProgram(command);
    }
}

//https://blog.csdn.net/qq_38446366/article/details/79714830
void CommandExecutor::executeCommand(const QString &command,QStringList &arguments) {
    if (command.startsWith("http://") || command.startsWith("https://")) {
        qDebug() << "------->http";
        openUrl(command);
    } else if (QFileInfo(command).isExecutable() && !command.endsWith(".lnk")) {
        qDebug() << "------->可执行非lnk";
        startExecutable(command,arguments);
    } else if (command.endsWith(".lnk")) {
        qDebug() << "------->lnk";
        openShortcut(command);
    } else if (command.contains(".exe") || command.contains(".bat") || command.contains(".cmd")) {
        qDebug() << "------->exe-bat-cmd";
        // replaceAtSymbolWithCurrentPath(command);
        startProcess(command, arguments);
    } else if (command.length() == 2 && command.endsWith(":")) {
        openDrive(command);
    } else if (command.length() == 3 && (command.endsWith("\\") || command.endsWith("/"))) {
        openDrive(command);
    } else if (systemIdentifiers.contains(command)) {
        qDebug() << "------->file";
        QString guid = systemIdentifiers.value(command);
        QUrl url("file:///" + guid);
        if (!QDesktopServices::openUrl(url)) {
            qDebug() << "Failed to open" << command;
        } else {
            qDebug() << "Opened" << command;
        }

        // QUrl controlPanelUrl("file:///::{21EC2020-3AEA-1069-A2DD-08002B30309D}");
        // if (!QDesktopServices::openUrl(controlPanelUrl)) {
        //     qDebug() << "Failed to open '控制面板'";
        // }
    } else {
        qWarning() << "Unknown command type:" << command;
        runProgram(command);
    }
}



QString CommandExecutor::ExtractFileName(const QString &FileName) {
    return QFileInfo(FileName).fileName();
}

QString CommandExecutor::ExtractFileExt(const QString &FileName) {
    return QFileInfo(FileName).suffix();
}

QString CommandExecutor::RemoveQuotationMark(const QString &str, const QString &mark) {
    QString result = str;
    if (result.startsWith(mark) && result.endsWith(mark)) {
        result = result.mid(1, result.length() - 2);
    }
    return result;
}


QString CommandExecutor::RemoveQuotationMark2(const QString &str, const QString &QuotationMark) {
    int QuotationLen = QuotationMark.length();
    if (str.length() < 2 * QuotationLen) {
        return str;
    }
    if (str.startsWith(QuotationMark) && str.endsWith(QuotationMark)) {
        QString strTemp = str.mid(QuotationLen, str.length() - 2 * QuotationLen);
        if (!strTemp.contains(QuotationMark)) {
            return strTemp;
        }
    }
    return str;
}


bool CommandExecutor::ReplaceEnvStr(QString &str) {
    m_Regex.setPattern("(%)(.*?)(%)");
    QRegularExpressionMatchIterator i = m_Regex.globalMatch(str);
    while (i.hasNext()) {
        QRegularExpressionMatch match = i.next();
        QString envVar = match.captured(2);
        QString envValue = QProcessEnvironment::systemEnvironment().value(envVar);
        if (!envValue.isEmpty()) {
            str.replace("%" + envVar + "%", envValue);
        }
    }
    return true;
}


QString CommandExecutor::ExtractFileDir(const QString &FileName) {
    return QFileInfo(FileName).path();
}

bool CommandExecutor::Execute(TCmdObject *cmdobj) {
    if (cmdobj->Command.isEmpty()) {
        return false;
    }

    QThread *thread = QThread::create([cmdobj]() {
        QProcess::startDetached(cmdobj->Command, QStringList() << cmdobj->Param, cmdobj->WorkingDir);
        delete cmdobj;
    });
    thread->start();

    // ShortCutRunCount++;

    // if ((ShortCutRunCount % 10000) == 0) {
    //     QMessageBox::information(nullptr, "Info", QString("Congratulations! You have run %1 shortcuts.").arg(ShortCutRunCount));
    // }

    return true;
}

bool CommandExecutor::Execute(TShortCutItem *ShortCutItem) {
    if (ShortCutItem->ShortCutType != scItem) {
        return false;
    }

    TCmdObject *cmdobj = new TCmdObject();

    cmdobj->Command = ShortCutItem->CommandLine;
    ReplaceEnvStr(cmdobj->Command);

    QString str = RemoveQuotationMark2(ShortCutItem->CommandLine.trimmed(), "\"");

    if (!str.startsWith("\\\\")) {
        if (QFile::exists(str)) {
            cmdobj->WorkingDir = ExtractFileDir(str);
        } else {
            if (str.startsWith("\"")) {
                cmdobj->WorkingDir = "";
                QString TrueCmdFile = str.mid(1, str.length() - 1);
                int FlagPos = TrueCmdFile.indexOf("\"");
                if (FlagPos > 0) {
                    TrueCmdFile = TrueCmdFile.left(FlagPos);
                    if (QFile::exists(TrueCmdFile)) {
                        cmdobj->Command = TrueCmdFile;
                        cmdobj->WorkingDir = ExtractFileDir(TrueCmdFile);
                        cmdobj->Param = str.mid(FlagPos + 2).trimmed();
                    }
                }
            }
        }
    }

    if (ShortCutItem->ParamType == ptNone) {
        if (cmdobj->Param.isEmpty()) {
            cmdobj->ParamType = ptNone;
        } else {
            cmdobj->ParamType = ptNoEncoding;
        }
        return Execute(cmdobj);
    } else {
        // 这里需要根据具体的逻辑来实现参数的处理
        // 例如：处理剪贴板、前台窗口ID等
        // 这部分逻辑需要根据具体需求来实现

        cmdobj->ParamType = ShortCutItem->ParamType;

        switch (ShortCutItem->ParamType) {
        case ptNoEncoding:
            break;
        case ptURLQuery:
            // 处理URLQuery
            break;
        case ptUTF8Query:
            // 处理UTF8Query
            break;
        case ptNone:
            break;
        }

        return Execute(cmdobj);
    }
}
